package com.jrx.anytxn.transaction.timer.job.loan.step;

import com.alibaba.fastjson.JSONObject;
import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.common.uitl.StringUtils;
import com.jrx.anytxn.feign.gateway.bean.ApiResponse;
import com.jrx.anytxn.feign.gateway.response.CoreResponse20;
import com.jrx.anytxn.feign.gateway.service.IInnerGatewayService;
import com.jrx.anytxn.feign.investor.request.InvestorCancelLoanReq;
import com.jrx.anytxn.feign.investor.request.LoanReq;
import com.jrx.anytxn.feign.investor.response.LoanRes;
import com.jrx.anytxn.feign.investor.service.IAnyTxnInvestorService;
import com.jrx.anytxn.i18n.response.TxnRespResult;
import com.jrx.anytxn.param.entity.PrOrganizationTable;
import com.jrx.anytxn.param.service.system.IOrganizationTableService;
import com.jrx.anytxn.transaction.bean.AfterSucSaveBean;
import com.jrx.anytxn.transaction.bean.LoanSaveBean;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.entity.AmLoanAccountInfo;
import com.jrx.anytxn.transaction.entity.AmLoanMainInfo;
import com.jrx.anytxn.transaction.entity.TlDisbursementLog;
import com.jrx.anytxn.transaction.entity.TlLoanClassifyChange;
import com.jrx.anytxn.transaction.handler.ILoanHandler;
import com.jrx.anytxn.transaction.mapper.ext.ExtAmLoanAccountInfoMapper;
import com.jrx.anytxn.transaction.mapper.ext.ExtAmLoanMainInfoMapper;
import com.jrx.anytxn.transaction.service.IDealGatewayService;
import com.jrx.anytxn.transaction.service.ILoanMainInfoService;
import com.jrx.anytxn.transaction.service.ILoanService;
import com.jrx.anytxn.transaction.service.IPartnerLimitRecoveryService;
import com.jrx.anytxn.transaction.service.ISmsService;
import com.jrx.anytxn.transaction.service.ITlLoanClassifyService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Objects;

/**
 * 放款 - processor
 *
 * @author jing.xy
 */
@Service
public class LoanProcessor implements ItemProcessor<TlDisbursementLog, LoanSaveBean> {

    Logger logger = LoggerFactory.getLogger(LoanProcessor.class);

    @Autowired
    private ILoanService loanService;
    @Autowired
    private IOrganizationTableService organizationTableService;
    @Autowired
    private IDealGatewayService dealGatewayService;
    @Lazy
    @Autowired
    private IInnerGatewayService innerGatewayService;
    @Autowired
    private ISmsService iSmsService;
    @Lazy
    @Autowired
    private IAnyTxnInvestorService anyTxnInvestorService;
    @Autowired
    private ILoanMainInfoService loanMainInfoService;
    @Autowired
    private IPartnerLimitRecoveryService partnerLimitRecoveryService;
    @Resource
    private ExtAmLoanMainInfoMapper extAmLoanMainInfoMapper;
    @Resource
    private ExtAmLoanAccountInfoMapper extAmLoanAccountInfoMapper;
    @Autowired
    private ITlLoanClassifyService tlLoanClassifyService;
    @Autowired
    private ILoanHandler iLoanHandler;

    @Override
    public LoanSaveBean process(TlDisbursementLog log) throws Exception {
        LoanSaveBean loanSaveBean = new LoanSaveBean();
        try {
            PrOrganizationTable organization = organizationTableService.findByOrId(log.getOrganizationId(), log.getTenantId());
            //机构上 当天日期
            Date businessDate = organization.getNextProcessingDate();
            Date completeDate = DateUtils.getBusinessTime(new Date(), businessDate);
            TlDisbursementLog updateLog = new TlDisbursementLog();
            updateLog.setId(log.getId());
            updateLog.setCustomerId(log.getCustomerId());
            updateLog.setTenantId(log.getTenantId());
            updateLog.setLaunchTime(DateUtils.getBusinessTime(new Date(), businessDate));

            boolean investorLoanResult = true;
            boolean isJointLoanFlag = TransBizConstant.YES_FLAG.equals(log.getJointLoanFlag());
            String thirdAcctNo = null;
            // 如果订单为联合贷订单
            AmLoanMainInfo loanMainInfo = loanMainInfoService.getAmLoanMainInfoByLoanIdAndCusId(log.getLoanId(), log.getCustomerId(), log.getTenantId());
            if (isJointLoanFlag) {
                // 调用资金源贷款确认接口
                LoanReq req = new LoanReq(log.getLoanId(), log.getCustomerId(), log.getTenantId(), log.getSeqNo(), log.getChannel(), log.getProductId(),
                        log.getAmount(), loanMainInfo.getAmortMethodTableId(), loanMainInfo.getTotalTenor());
                TxnRespResult<LoanRes> txnRespResult = anyTxnInvestorService.loan(req);
                investorLoanResult = txnRespResult != null && txnRespResult.getCode() == 1000;
                if(investorLoanResult){
                    thirdAcctNo = txnRespResult.getData().getThirdAcctNo();
                }
            }

            if (!investorLoanResult) {
                // 如果联合贷放款失败,则更新对客放款流水为失败
                updateLog.setSumStatus(TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_F);
    //            updateLog.setCancelStatus(TransBizConstant.YES_FLAG);
                updateLog.setCompleteTime(DateUtils.getBusinessTime(new Date(), businessDate));

                // 资金源订单撤销
                InvestorCancelLoanReq req = new InvestorCancelLoanReq(log.getLoanId(), log.getCustomerId(), log.getTenantId(), log.getSeqNo(), log.getChannel(), loanMainInfo.getFundId(), log.getProductId());
                anyTxnInvestorService.cancelLoan(req);

                // 取消对客订单
    //            CancelSaveBean cancelSaveBean = loanService.cancelOrder(log.getLoanId(),
    //                    log.getCustomerId(), log.getTenantId(), businessDate);
    //            loanSaveBean.setCancelSaveBean(cancelSaveBean);

                loanSaveBean.setUpdateLog(updateLog);
            } else {
                // 如果是非联合贷订单或者联合贷放款成功，则调用对客放款接口
                // 受托支付不上送身份证和手机号
                if (TransBizConstant.YES_FLAG.equals(log.getEntrustedPayment())) {
                    log.setMobile(null);
                }
                String result = "";
                String busCode = "";
                String busMsg = "";
                // D 待发起放款 从内部户到过渡户 后 从过渡户到用户卡号
                // PYMT001190（他行）+ACPG000090（本行）
                String paymentRequest06Json = dealGatewayService.buildInnerDisbursementReq(log);
                ApiResponse<CoreResponse20> response = innerGatewayService.refund(paymentRequest06Json);
                logger.info("ACPG000090,用户：{}interestCompensate结果：{}", log.getCustomerId(), JSONObject.toJSONString(response));
                if (Objects.isNull(response) || Objects.isNull(response.getData())
                        || TransBizConstant.GATEWAY_SUC != response.getCode() || response.getData().getBusMsg().contains(TransBizConstant.GATEWAY_CONTENT_TIMEOUT)) {
                    logger.warn("调用放款接口出现异常:{}", JSONObject.toJSONString(response));
                    updateLog.setSumStatus(TransBizConstant.PAYMENT_LOG_SUM_STATUS_O);
                    updateLog.setCompleteTime(DateUtils.getBusinessTime(new Date(), businessDate));
                    loanSaveBean.setUpdateLog(updateLog);
                    return loanSaveBean;
                }
                CoreResponse20 res = response.getData();
                result = res.getDealResult();
                busCode = res.getBusCode();
                busMsg = res.getBusMsg();
                updateLog.setReturnCode(busCode);
                log.setReturnMessage(busMsg);
                updateLog.setReturnMessage(busMsg);
                updateLog.setReturnStatus(result);
                // 设置响应状态
                this.setSumStatus(log, businessDate, updateLog, result);
                updateLog.setSettleChannel(res.getSysCode());
                updateLog.setCompleteTime(completeDate);
                String transactionId25 = res.getTransactionId25();
                if (StringUtils.isNotBlank(transactionId25)) {
                    // 设置核心FT流水号
                    updateLog.setCoreSeq(transactionId25);
                }
                if (TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_S.equals(updateLog.getSumStatus())) {
                    //成功
                    AmLoanMainInfo amLoanMainInfo = extAmLoanMainInfoMapper.selectByLoanIdAndCusId(log.getLoanId(), log.getCustomerId(), log.getTenantId());
                    AmLoanAccountInfo amLoanAccountInfo = extAmLoanAccountInfoMapper.selectByLoanId(log.getLoanId(), log.getCustomerId(), log.getTenantId());

                    //放款成功记录五级分类变动
                    TlLoanClassifyChange tlLoanClassifyChange = tlLoanClassifyService.buildLoanClassifyChange(amLoanAccountInfo, businessDate, amLoanMainInfo.getLoanAmount(), TransBizConstant.LOAN_CLASSIFY_0);
                    loanSaveBean.setTlLoanClassifyChange(tlLoanClassifyChange);

                    AfterSucSaveBean afterSucSaveBean = loanService.afterLoanSuccess(amLoanMainInfo, amLoanAccountInfo, businessDate);
                    loanSaveBean.setAfterSucSaveBean(afterSucSaveBean);


                } else if (TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_F.equals(updateLog.getSumStatus())) {
                    // 失败
                    updateLog.setCancelStatus(TransBizConstant.NO_FLAG);
                    updateLog.setCancelWhenFail(TransBizConstant.CANCLE_STATUS_1);

                    if (isJointLoanFlag) {
                        // 如果是联合贷订单则撤销资金源订单撤销
                        InvestorCancelLoanReq req = new InvestorCancelLoanReq(log.getLoanId(), log.getCustomerId(), log.getTenantId(), log.getSeqNo(), log.getChannel(), loanMainInfo.getFundId(), log.getProductId());
                        anyTxnInvestorService.cancelLoan(req);
                    }

                    //CancelSaveBean cancelSaveBean = loanService.cancelOrder(log.getLoanId(),
                    //        log.getCustomerId(), log.getTenantId(), businessDate);
                    //loanSaveBean.setCancelSaveBean(cancelSaveBean);
                    //放款失败合作方额度恢复
                    //partnerLimitRecoveryService.partnerLimitRecovery(log.getProductId(), log.getOrganizationId(),
                    //        log.getTenantId(), log.getAmount(), log.getSeqNo());
                } else { //其他
                    updateLog.setSumStatus(TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_O);
                }
                loanSaveBean.setUpdateLog(updateLog);
            }
            // 本行卡直接出结果，他行卡以查询或者回调为准
            if (Objects.equals(TransBizConstant.CARD_TYPE_0,log.getPayeeAccountType())) {
                // 发送短信
                sendDisbursementMsg(log, completeDate, updateLog, loanMainInfo);
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("LoanProcessor发生了异常：{}", e.getMessage());
        }

        return loanSaveBean;
    }

    /**
     * 发送短信
     * @param log
     * @param completeDate
     * @param updateLog
     * @param loanMainInfo
     */
    public void sendDisbursementMsg(TlDisbursementLog log, Date completeDate, TlDisbursementLog updateLog, AmLoanMainInfo loanMainInfo) {
        //只有拿到终态的才需要发送短信
        if (!updateLog.getSumStatus().equals(TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_O)) {
            //兴安付发送受托支付通知短信所做的兼容处理
            //if (Constants.XAF_PRODUCT_CODE.equals(log.getProductId())) {
            //    OrderInfoRes orderInfoRes = iLoanHandler.queryOrderInfo(log.getLoanId(), log.getCustomerId()).getData();
            //    log.setMobile(orderInfoRes.getMerChantMobile());
            //    log.setLoanId(orderInfoRes.getOrderNo());
            //    log.setAmount(orderInfoRes.getLoanAmt());
            //}
            //放款后短信处理 获取短信规则 发送放款短信MQ消息
            log.setSumStatus(updateLog.getSumStatus());
            try {
                iSmsService.disbursementProcess(log);
            } catch (Exception e) {
                logger.error("短信发送异常", e);
            }
            try {
                // 通知api-server放款状态更新
                iLoanHandler.disbursementStatus(log, completeDate, loanMainInfo.getContractNumber());
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("通知api异常:{}", e.getMessage());
            }
        }
    }

    /**
     * 设置响应状态
     * @param log
     * @param businessDate
     * @param updateLog
     * @param result
     */
    public void setSumStatus(TlDisbursementLog log, Date businessDate, TlDisbursementLog updateLog, String result) {
        if (TransBizConstant.GATEWAY_DEAL_SUC.equals(result)) {
            updateLog.setSumStatus(TransBizConstant.PAYMENT_LOG_SUM_STATUS_S);
            //转账成功
            updateLog.setCollateDate(businessDate);
        } else if (TransBizConstant.GATEWAY_DEAL_FAIL.equals(result)) {
            //转账失败
            updateLog.setSumStatus(TransBizConstant.PAYMENT_LOG_SUM_STATUS_F);
            updateLog.setCollateDate(businessDate);
        } else {
            //转账状态未知-其他
            updateLog.setSumStatus(TransBizConstant.PAYMENT_LOG_SUM_STATUS_O);
        }
        if (TransBizConstant.CARD_TYPE_1.equals(log.getPayeeAccountType())) {
            updateLog.setSumStatus(TransBizConstant.PAYMENT_LOG_SUM_STATUS_O);
        }
    }

}
